#ifndef PARSER_EDIT_H
#define PARSER_EDIT_H

#include "ParserBase.h"
#include "CommandEdit.h"

/**
 * Handles edit commands 
 *
 * 
 *
 * The following are handled in accordance with the priority
 * Assume argument is a datetime
 * Assume argument is a time (only)
 *
 @author Ling Chun Kai

*/

using namespace std;
using namespace boost::posix_time;

class ParserEdit : public ParserBase {
public:
	ParserEdit(ParserBase* _nextParser);
private:
	enum {INSTRUCTION_POS = 1, ARGUMENTS_POS, NUM_MAJOR_SEGMENTS};
	enum EditSubType {EDIT_START, EDIT_END, EDIT_NAME, INVALID_SUBTYPE};

	// The following are regex constants used for parsing
	static const string regexInstructionAndArguments;

	static const string regexArgumentEditStart;
	static const string regexArgumentEditEnd;
	static const string regexArgumentEditRename;

	// These are the keywords allowed for instructions
	static const string regexInstructionEdit;
	
	// These are the positions of the extracted arguments in the smatch
	// structure after extracting arguments.
	static const int ARGUMENT_POS_EDIT_TASKID = 1;
	
	static const int ARGUMENT_POS_EDIT_NEW_NAME = 2;
	static const int ARGUMENT_POS_EDIT_NEW_START = 2;
	static const int ARGUMENT_POS_EDIT_NEW_END = 2;

	bool tryParse(string userCommand, CommandBase* parsedCommand);

	// This method takes a user command and splits it into the instruction and 
	// argument components
	bool getInstructionAndArguments(const string& userCommand, 
									string& instruction, 
									string& arguments);

	// This method checks that the instruction is of the type 'edit'
	bool checkInstruction(const string& instruction);

	// This method parses the arguments provided to an edit Instruction
	// and stores them in the PARSED_COMMAND struct passed.
	void parseEdit(CommandBase* parsedCommand,
				  const string& arguments);

	// The following method categorize the actual CommandType based on the arguments provided.
	// It returns the appropriate command type. matchingArguments will be 
	// filled up with the relevant details upon successful completion
	EditSubType categorizeEditCommand(const string& arguments, smatch& matchingArguments);

	// This method fills a PARSED_COMMAND struct with information indicating that
	// there was an error in syntax within - eg. it did couldn't be classified 
	// as any one of the subtypes defined.
	void ParserEdit::makeParsedCommandEditErrorSyntax(CommandBase* parsedCommand, 
											  smatch& matchingArguments);
	// This method parses and fills up a PARSED_COMMAND struct based
	// on the subtype of the command edit idenfitied.
	void ParserEdit::makeParsedCommandEditRename(CommandBase* parsedCommand, 
											  smatch& matchingArguments);
	void ParserEdit::makeParsedCommandEditStart(CommandBase* parsedCommand, 
											  smatch& matchingArguments);
	void ParserEdit::makeParsedCommandEditEnd(CommandBase* parsedCommand, 
											  smatch& matchingArguments);

};

#endif